home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / nrlogind.zip / RCMD.C < prev    next >
C/C++ Source or Header  |  1994-02-18  |  6KB  |  215 lines

  1. /*
  2.  * Copyright (C) 1994 Nathaniel W. Mishkin.
  3.  * All rights reserved.
  4.  */
  5.  
  6. /*
  7.  * Copyright (C) 1983 Regents of the University of California.
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  */
  38.  
  39. #if defined(LIBC_SCCS) && !defined(lint)
  40. static char sccsid[] = "@(#)rcmd.c    5.24 (Berkeley) 2/24/91";
  41. #endif /* LIBC_SCCS and not lint */
  42.  
  43. #include <winsock.h>
  44. #include <windows.h>
  45. #include <io.h>
  46.  
  47. #include <sys/stat.h>
  48. #include <errno.h>
  49. #include <stdio.h>
  50. #include <ctype.h>
  51. #include <string.h>
  52.  
  53. rresvport(int *alport);
  54.  
  55. rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
  56.     char **ahost;
  57.     u_short rport;
  58.     const char *locuser, *remuser, *cmd;
  59.     int *fd2p;
  60. {
  61.     int s, timo = 1;
  62.     struct sockaddr_in sin, from;
  63.     char c;
  64.     int lport = IPPORT_RESERVED - 1;
  65.     struct hostent *hp;
  66.     fd_set reads;
  67.  
  68.     hp = gethostbyname(*ahost);
  69.     if (hp == 0) {
  70.         fprintf(stderr, "gethostbyname: %s\n", *ahost);
  71.         return (-1);
  72.     }
  73.     *ahost = hp->h_name;
  74.     for (;;) {
  75.         s = rresvport(&lport);
  76.         if (s < 0) {
  77.             if (WSAGetLastError() == EAGAIN)
  78.                 fprintf(stderr, "socket: All ports in use\n");
  79.             else
  80.                 perror("rcmd: socket");
  81.             return (-1);
  82.         }
  83.         sin.sin_family = hp->h_addrtype;
  84.         memcpy((void *)&sin.sin_addr, hp->h_addr_list[0], hp->h_length);
  85.         sin.sin_port = rport;
  86.         if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
  87.             break;
  88.         (void) closesocket(s);
  89.         if (WSAGetLastError() == WSAEADDRINUSE) {
  90.             lport--;
  91.             continue;
  92.         }
  93.         if (WSAGetLastError() == WSAECONNREFUSED && timo <= 16) {
  94.             Sleep(timo * 1000);
  95.             timo *= 2;
  96.             continue;
  97.         }
  98.         if (hp->h_addr_list[1] != NULL) {
  99.             int oerrno = WSAGetLastError();
  100.  
  101.             fprintf(stderr,
  102.                 "connect to address %s: ", inet_ntoa(sin.sin_addr));
  103.             WSASetLastError(oerrno);
  104.             perror(0);
  105.             hp->h_addr_list++;
  106.             memcpy((void *)&sin.sin_addr, hp->h_addr_list[0], 
  107.                 hp->h_length);
  108.             fprintf(stderr, "Trying %s...\n",
  109.                 inet_ntoa(sin.sin_addr));
  110.             continue;
  111.         }
  112.         perror(hp->h_name);
  113.         return (-1);
  114.     }
  115.     lport--;
  116.     if (fd2p == 0) {
  117.         send(s, "", 1, 0);
  118.         lport = 0;
  119.     } else {
  120.         char num[8];
  121.         int s2 = rresvport(&lport), s3;
  122.         int len = sizeof (from);
  123.  
  124.         if (s2 < 0)
  125.             goto bad;
  126.         listen(s2, 1);
  127.         (void) sprintf(num, "%d", lport);
  128.         if (send(s, num, strlen(num)+1, 0) != (int) strlen(num)+1, 0) {
  129.             perror("write: setting up stderr");
  130.             (void) closesocket(s2);
  131.             goto bad;
  132.         }
  133.         FD_ZERO(&reads);
  134.         FD_SET(s, &reads);
  135.         FD_SET(s2, &reads);
  136.         WSASetLastError(0);
  137.         if (select(32, &reads, 0, 0, 0) < 1 ||
  138.             !FD_ISSET(s2, &reads)) {
  139.             if (WSAGetLastError() != 0)
  140.                 perror("select: setting up stderr");
  141.             else
  142.                 fprintf(stderr,
  143.                 "select: protocol failure in circuit setup.\n");
  144.             (void) closesocket(s2);
  145.             goto bad;
  146.         }
  147.         s3 = accept(s2, (struct sockaddr *)&from, &len);
  148.         (void) closesocket(s2);
  149.         if (s3 < 0) {
  150.             perror("accept");
  151.             lport = 0;
  152.             goto bad;
  153.         }
  154.         *fd2p = s3;
  155.         from.sin_port = ntohs((u_short)from.sin_port);
  156.         if (from.sin_family != AF_INET ||
  157.             from.sin_port >= IPPORT_RESERVED ||
  158.             from.sin_port < IPPORT_RESERVED / 2) {
  159.             fprintf(stderr,
  160.                 "socket: protocol failure in circuit setup.\n");
  161.             goto bad2;
  162.         }
  163.     }
  164.     (void) send(s, locuser, strlen(locuser)+1, 0);
  165.     (void) send(s, remuser, strlen(remuser)+1, 0);
  166.     (void) send(s, cmd, strlen(cmd)+1, 0);
  167.     if (recv(s, &c, 1, 0) != 1) {
  168.         perror(*ahost);
  169.         goto bad2;
  170.     }
  171.     if (c != 0) {
  172.         while (recv(s, &c, 1, 0) == 1) {
  173.             (void) write(2, &c, 1);
  174.             if (c == '\n')
  175.                 break;
  176.         }
  177.         goto bad2;
  178.     }
  179.     return (s);
  180. bad2:
  181.     if (lport)
  182.         (void) closesocket(*fd2p);
  183. bad:
  184.     (void) closesocket(s);
  185.     return (-1);
  186. }
  187.  
  188. rresvport(alport)
  189.     int *alport;
  190. {
  191.     struct sockaddr_in sin;
  192.     int s;
  193.  
  194.     sin.sin_family = AF_INET;
  195.     sin.sin_addr.s_addr = INADDR_ANY;
  196.     s = socket(AF_INET, SOCK_STREAM, 0);
  197.     if (s < 0)
  198.         return (-1);
  199.     for (;;) {
  200.         sin.sin_port = htons((u_short)*alport);
  201.         if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  202.             return (s);
  203.         if (WSAGetLastError() != WSAEADDRINUSE) {
  204.             (void) closesocket(s);
  205.             return (-1);
  206.         }
  207.         (*alport)--;
  208.         if (*alport == IPPORT_RESERVED/2) {
  209.             (void) closesocket(s);
  210.             WSASetLastError(EAGAIN);        /* close */
  211.             return (-1);
  212.         }
  213.     }
  214. }
  215.